package com.exam.scjp5.objectives.section_4;

public class ExampleSynchronizedTest
{
    public static void main(String args[])
    {
        CommonObject commonObject = new CommonObject();
        WriterThread w = new WriterThread();
        ReaderThread r = new ReaderThread();

        w.setCommonObject(commonObject);
        r.setCommonObject(commonObject);

        w.start();
        r.start();
    }
}

class WriterThread extends Thread
{
    private CommonObject commonObject = null;

    public CommonObject getCommonObject()
    {
        return commonObject;
    }

    public void setCommonObject(CommonObject commonObject)
    {
        this.commonObject = commonObject;
    }

    public void run()
    {

        synchronized (this.commonObject)
        {
            for (int i = 0; i < 10; i++)
            {

                this.commonObject.setValue(i);
                System.out.println("Writer put : " + this.commonObject.getValue());
                try
                {
                    Thread.currentThread().sleep(1000);
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
            this.commonObject.notifyAll();
        }
    }
}

class ReaderThread extends Thread
{
    private CommonObject commonObject = null;

    public CommonObject getCommonObject()
    {
        return commonObject;
    }

    public void setCommonObject(CommonObject commonObject)
    {
        this.commonObject = commonObject;
    }

    public void run()
    {
        //for (int i = 0; i < 20; i++)
        //{
            
        try
        {
            synchronized(this.commonObject) 
            // If you removed 'synchronized' here, you will get IllegalMonitoringStateException
            {
                this.commonObject.wait();
            }
            System.out.println("Reader get : " + this.commonObject.getValue());
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //}
    }
}

class CommonObject
{
    private int value = 0;

    public int getValue()
    {
        return value;
    }

    public void setValue(int value)
    {
        this.value = value;
    }
}

